#ifndef TASKHIGHLIGHT_H_
#define TASKHIGHLIGHT_H_

#include <string>
#include <vector>
#include <list>
#include <utility>
#include <libxml/HTMLparser.h>
#include <libxml/HTMLtree.h>
#include <boost/signals2.hpp>
#include "../Psqldb/IDatabase.h"
#include "../Server/SRVConnection.h"
#include "ITask.h"


namespace Tasks{


	namespace {

		typedef unsigned int index;

		static const std::wstring highlight_prefix =  L"<font color=\"red\"><b>";
		static const std::wstring highlight_postfix = L"</b></font>";

		//////////////////////////////////////////////////////////////////////////
		//							CLASS HTMLREADER							//
		//////////////////////////////////////////////////////////////////////////
		class HtmlReader
		{
			public:
				HtmlReader(std::string theFile);
				~HtmlReader(void);

				boost::signals2::signal<char* (const unsigned char*,unsigned char*)> OnTextParsed;

				bool StartParsing();

				bool Save(std::string theOutput);

			private:
				htmlDocPtr myHtmlDoc;
				void postprocess(std::string theFile);
				void walk_tree(xmlNode *theNode);
		};
		
		//////////////////////////////////////////////////////////////////////////
		//							CLASS HIGHLIGHTER							//
		//////////////////////////////////////////////////////////////////////////
		class Highlighter
		{
		public:
			Highlighter(void);

			//! Open (public )
			/*!
			Funkcia sluzi na nacitanie html stranky a indexov slov ktore sa
			maju vyznacit
			\param const std::string & theMatchIndexes indexy
			\param const std::string & thePathToHtml cesta k html stranke
			\return bool true ak sa uspesne nacitali udaje, false inak
			*/
			bool Open(const std::string &theMatchIndexes,const std::string &thePathToHtml);


			//void Process(std::string &theOutput);

			//! Higlight(public )
			/*!
			Sluzi na vyznacenie slov v samotnej web stranke 
			\return void
			*/
			void Higlight(void);

			//! Save (public )
			/*!
				Funkcia ulozi webstranku s vyraznenimy castami  
				\param std::string whereTo cesta kam sa ulozi aj s nazvom
				\return bool true ak uspesne sa ulozi, false inak
			*/
			bool Save(std::string whereTo);

		private:
			HtmlReader *myReader;
			index myIndexStart;
			index myLastIndex;
			index myIndexCount;
			bool myStartParse;
			std::vector<std::pair<index,index> > myIndexes;

			//! ConvertIndex (private )
			/*!
			Prekonvertuje indexi reprezentovane v stringu na 
			vector indexovych parov
			\param const std::string & theMatchIndexes indexi v string reprezentacii
			\return bool true ak uspesne, false inak
			*/
			bool ConvertIndex(const std::string &theMatchIndexes);

			//! UpdateIndexes (private )
			/*!
			Funkcia zmeni(posunie) indexi o urcitu hodnotu 
			\param std::size_t from_index urcuje od ktoreho indexu sa robi zmena
			\param std::size_t theOffset hodnota posunu kazdeho indexu
			\return void
			*/
			void UpdateIndexes(std::size_t from_index,std::size_t theOffset);

			//! UpdateIndexes (private )
			/*!
			Funkcia zmeni(posunie) indexi o urcitu poziciu(aj zapornu) 
			\param std::size_t from_index urcuje od ktoreho indexu sa robi zmena
			\param int theOffset hodnota posunu kazdeho indexu (moze byt aj zaporna)
			\return void
			*/
			void UpdateIndexes(std::size_t from_index, int theOffset);


			//! parsed_part (private )
			/*!
				Funkcia ktora sa vola ak sa sparsuje ista cast web stranky
				\param const unsigned char * nodeName nazov sparsovaneho uzla
				\param unsigned char * nodeValue jeho obsah(hodnota)
				\return char* NULL ak ziadne zmeny v obsahu ,alebo novy obsah v pripade zmeny
			*/
			char* parsed_part(const unsigned char* nodeName,unsigned char* nodeValue);

			//! normalize (private )
			/*!
				Normalizacia obsahu sparsovanej casti web stranky
				\param std::wstring & input
				\return void
			*/
			void normalize(std::wstring &input);

			void kill_newlines(std::wstring &input);
		};
		
	}//end of anonym namespace



//! Trieda TaskHighlight
/*!
	Sluzi na zvyraznenie zhodnych casti dokumentov.
	Zvyraznovanie sa vykonava v html strankach.
*/
class TaskHighlight : public ITask<Data>
{
	public:

		//! TaskHighlight (public )
		/*!
			Popis.... 
			\param DB::IDatabase * pDbConnection
			\return 
		*/
		TaskHighlight(DB::IDatabase *pDbConnection);
		
		//! operator() (virtual public )
		/*!
			Popis.... 
			\return void
		*/
		virtual void operator()();

	private:
		DB::IDatabase *my_pDbConnection;
		Highlighter myHighlighter;
};

}//end of namespace Tasks

#endif//TASKHIGHLIGHT_H_